/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package creature;

import java.awt.Color;
import java.util.Vector;
import world.World;

/**
 *
 * @author leadiv
 *  By Default a creature is a small green 1 pixel dot that runs east to west.
 */
public class Creature4 extends Creature {
    private int lonely;  //Threshold
    private int happy;   //Threshold
    private int crowded; //Threshold
    private float stickiness;
    private float movThreshold;
    private float moveDelta;
    private float birthThreshold;
    private float deathcnt;
    private float deathThreshold;
    private float deathDelta;

    public Creature4(int x, int y, int id) {
        super(x,y,id);

        int t1, t2;
        t1 = (int)(Math.random() * 7);
        t2 = (int)(Math.random() * 7);
        this.moveDelta = (float)(Math.random() * .1);
        this.movThreshold = (float)(Math.random() * .2) + .8f;  // move threshold is somewhere between .5 and .999
        this.stickiness = -1f;                                  // the lower the stickiness the less cohesive the creatures are
        this.birthThreshold = 3f;
        this.deathThreshold = (float)(Math.random() * .5);
        this.deathcnt = 1f;
        this.deathDelta = -(float)(Math.random() * .1);       // really low is good

        if(t1 > t2) {
            this.lonely = t2;
            this.happy = t1;
        } else {
            this.lonely = t1;
            this.happy = t2;
        }

        this.crowded = 7;
    }
    
    @Override
    public void move(World w) {
       Color[] neighbors = new Color[8];
       int cnt=0, avg1, avg2, avg3, sum, mov, i;
       Vector<Integer> high = new Vector<Integer>(),
                       mid = new Vector<Integer>(),
                       low = new Vector<Integer>();    // this is for density index values.

       neighbors[0] = w.getpix(this.getX()-1, this.getY()+1);
       neighbors[1] = w.getpix(this.getX()  , this.getY()+1);
       neighbors[2] = w.getpix(this.getX()+1, this.getY()+1);
       neighbors[3] = w.getpix(this.getX()-1, this.getY());
       neighbors[4] = w.getpix(this.getX()+1, this.getY());
       neighbors[5] = w.getpix(this.getX()-1, this.getY()-1);
       neighbors[6] = w.getpix(this.getX()  , this.getY()-1);
       neighbors[7] = w.getpix(this.getX()+1, this.getY()-1);



       for(i=0; i<8; i++) {
           avg1 = neighbors[(i-1<0)?7:i].equals(Color.BLACK) ? 0 : 1;
           avg2 = neighbors[i].equals(Color.BLACK) ? 0 : 1;
           avg3 = neighbors[(i+1)%8].equals(Color.BLACK) ? 0 : 1;
           if(0 == avg2) {  // this spot is empty
               sum = avg1+avg2+avg3;
               if(sum == 2) high.add(i);
               if(sum == 1) mid.add(i);
               if(sum == 0) low.add(i);
           } else {
               cnt++;
           }
       }


       // as time wears on you have a higher probablity of dying
       this.deathcnt += this.deathDelta;
       if(this.deathcnt < this.deathThreshold) {
           this.setSkinColor(Color.BLACK);
           w.death(this.getX(), this.getY(), this.getId(), this);
           return;
       }

       if(cnt <= this.lonely) { // seek greatest density
           this.deathcnt += this.deathDelta;    // those who are lonely have a faster chance of dying
           if(this.stickiness > this.movThreshold) {    // don't move we like where we are even though its not the best situation
               this.stickiness -= this.moveDelta;
           }

           if(!high.isEmpty()) {
               mov = high.get(Double.valueOf(Math.random() * high.size()).intValue());
           } else if(!mid.isEmpty()) {
               mov = mid.get(Double.valueOf(Math.random() * mid.size()).intValue());
           } else {
               mov = low.get(Double.valueOf(Math.random() * low.size()).intValue());
           }

           w.place(this.getX() + World.MOVE[mov].x, this.getY() + World.MOVE[mov].y, this.getId());
           this.setSkinColor(Color.GREEN);
           return;
       }

       if(cnt <= this.happy) { // we are happy where we are -- don't move; give birth
           if(this.stickiness > this.birthThreshold) {
               high.addAll(mid);
               high.addAll(low);
               mov = high.get(Double.valueOf(Math.random() * high.size()).intValue());

               w.birth(this.getX() + World.MOVE[mov].x, this.getY() + World.MOVE[mov].y);
           }

           // once we find a group we like we tend to stick with the group the longer we are there
           this.stickiness += this.moveDelta;
           this.setSkinColor(Color.YELLOW);
           return;
       }


       if(cnt <= this.crowded) { // seek the least dense spot
           this.deathcnt += this.deathDelta;    // those who are lonely have a faster chance of dying
           
           if(this.stickiness > this.movThreshold) {    // don't move we like where we are even though its not the best situation
               this.stickiness -= this.moveDelta;
           }

           if(!low.isEmpty()) {
               mov = low.get(Double.valueOf(Math.random() * low.size()).intValue());
           } else if(!mid.isEmpty()) {
               mov = mid.get(Double.valueOf(Math.random() * mid.size()).intValue());
           } else {
               mov = high.get(Double.valueOf(Math.random() * high.size()).intValue());
           }

           w.place(this.getX() + World.MOVE[mov].x, this.getY() + World.MOVE[mov].y, this.getId());
           this.setSkinColor(Color.RED);
       }

       if(cnt == 8) { // can't move
           this.deathcnt += (this.deathDelta * 4);    // those who cant move have a greater chance of dying
           this.setSkinColor(Color.MAGENTA);
           return;
       }
    }

    @Override
    public boolean isDead() {
       return (this.getSkinColor() == Color.BLACK);
    }
}
